<template>
  <div class="designer" ref="designer" v-loading="template.loading" element-loading-text="检验模板加载中,请稍后..." element-loading-spinner="el-icon-loading">
    <div class="container">
      <field-list ref="fieldList"> </field-list>
      <div :class="editorAreaClass">
        <div class="editor-baseInfo">
          <div class="btnGroups" @click="handleToggleAttr">
            <el-tooltip effect="dark" content="操作" placement="bottom">
              <i class="el-icon-setting"></i>
            </el-tooltip>
          </div>
          <div class="editor-baseInfo-name">模板名称：{{ dataJson.name }} 模板类型：{{ dataJson.type }}</div>
          <div class="legend">
            <div class="legend-item api">红色: 非文本类型API接口数据</div>
          </div>
        </div>
        <menu-btn-groups ref="menuBtnGroups" @initForm="initForm" @handleSaveData="handleSave" @handleAddTemplateSuccess="handleAddTemplateSuccess"></menu-btn-groups>
        <div class="editor-canvas" v-if="dataJson.rows && dataJson.rows.length > 0" @click="handleClickEditor">
          <div class="grid-canvas" :style="canvasStyle" @mousedown="handleMouseDown" @mouseup="handleMouseUp" @contextmenu="handleContextMenu">
            <div class="x-Axis" @mousemove="handleXAxisMouseMove" @mouseup="handleXAxisMouseUp">
              <div class="x-Axis-item origin"></div>
              <div
                class="x-Axis-item"
                v-for="(item, index) in xAxisNum"
                :key="index"
                :index="index"
                :style="{ width: (item.width || baseTableConfig.cellWidth) - 1 + 'px' }"
                :class="{ active: item.active, selected: item.selected }"
                @click="batchXActive(item)"
              >
                {{ item.label }}
              </div>
              <!-- x轴辅助线 -->
              <div class="x-subline" :style="{ left: xSublineGuideLeft + 5 + 'px' }" v-if="showXSubline"></div>
              <!-- x轴拖拽块 -->
              <div
                class="x-subline-guide"
                :style="{ left: xSublineGuideLeft + 'px' }"
                v-if="showXSublineGuide"
                @mousedown="handleXGuideMouseDown"
                @mouseup="handleXGuideMouseUp"
              ></div>
              <div class="x-width-tip" :style="{ left: xSublineGuideLeft + 15 + 'px' }" v-if="showXSubline">宽度：{{ xSublineGuideLeft - 50 - frontXAxisTotalWidth }}像素</div>
            </div>

            <div class="y-Axis" @mousemove="handleYAxisMouseMove" @mouseup="handleYAxisMouseUp">
              <div class="y-Axis-item origin"></div>
              <div
                class="y-Axis-item"
                v-for="(item, index) in yAxisNum"
                :key="index"
                :index="index"
                :class="{ active: item.active, selected: item.selected }"
                :style="{ height: (item.height || baseTableConfig.cellHeight) - 1 + 'px', 'line-height': (item.height || baseTableConfig.cellHeight) - 1 + 'px' }"
                @click="batchYActive(item)"
              >
                {{ item.index }}
              </div>

              <!-- y轴辅助线 -->
              <div class="y-subline" :style="{ top: ySublineGuideTop + 5 + 'px' }" v-if="showYSubline"></div>
              <!-- y轴拖拽块 -->
              <div
                class="y-subline-guide"
                :style="{ top: ySublineGuideTop + 'px' }"
                v-if="showYSublineGuide"
                @mousedown="handleYGuideMouseDown"
                @mouseup="handleYGuideMouseUp"
              ></div>
              <div class="y-width-tip" :style="{ top: ySublineGuideTop + 15 + 'px' }" v-if="showYSubline">高度：{{ ySublineGuideTop - 30 - frontYAxisTotalHeight }}像素</div>
            </div>

            <table ref="tableDom" class="template-table" id="printTable" border="1" cellspacing="0" cellpadding="0" :style="computedTableStyle">
              <colgroup>
                <col :style="{ width: (item.width || baseTableConfig.cellWidth) + 'px' }" v-for="(item, index) in xAxisNum" :key="index" />
              </colgroup>
              <tr v-for="(item, index) in dataJson.rows" :key="index">
                <td
                  v-for="(cItem, cIndex) in computedNotHide(item.cells)"
                  :key="cIndex"
                  :x="cItem.x"
                  :y="cItem.y"
                  :class="[
                    'tdCell',
                    cellInfo.y == cItem.y + 1 && cellInfo.x == cItem.x + 1 && !showBoxArea ? 'active' : '',
                    cItem.type == 'text' && cItem.apiField ? 'apiField' : ''
                  ]"
                  :style="computedTdStyle(cItem.style)"
                  :rowspan="cItem.merge && cItem.merge.length == 2 ? cItem.merge[0] : 1"
                  :colspan="cItem.merge && cItem.merge.length == 2 ? cItem.merge[1] : 1"
                  @click="handleCellClick(cItem)"
                  @dblclick="handleCellDbClick(cItem)"
                  @dragover.prevent
                  @drop="handleDrop($event, cItem)"
                >
                  <i v-if="cItem.isLock" class="lockIcon el-icon-lock"></i>
                  <template v-if="cItem.type == 'text' && !cItem.isEdit">{{ cItem.code }}</template>
                  <shd-form-design-text
                    v-else-if="cItem.type == 'text' && cItem.isEdit"
                    :ref="cItem.x + '-' + cItem.y + '-comp'"
                    :is="formatterCompType(cItem.type)"
                    :tdStyle="computedComponentStyle(cItem.style)"
                    :value="cItem.value"
                    :disabled="true"
                    :dicData="cItem.dicData"
                    @input="handleCompInput"
                    @change="handleCompChange"
                  />
                  <shd-model-comp
                    v-else
                    :tdStyle="computedComponentStyle(cItem.style)"
                    :value="cItem.value"
                    :type="cItem.type"
                    :disabled="true"
                    :dataType="cItem.dataType"
                    :dicData="cItem.dicData"
                  ></shd-model-comp>
                </td>
              </tr>
            </table>
            <div title="打印线" class="print-line" :style="computedPrintLineStyle"></div>

            <!-- 右击菜单 -->
            <contextMenu v-show="showContextMenu" :top="contextMenu.top" :left="contextMenu.left" @command="command"></contextMenu>
            <!-- 框选区域 -->
            <boxArea v-if="showBoxArea" :boxAreaStyle="boxAreaStyle" @clearBoxArea="clearBoxAreaStyle"></boxArea>
          </div>
        </div>
      </div>

      <attr-config ref="attrConfig"></attr-config>
    </div>
  </div>
</template>
<script>
import { propertyList } from './property.js';
import { calculateBoxAreaStyle, isClickSameCell, findParentWithClass, pageSizeInPixels } from './util.js';
import boxArea from './boxArea.vue';
import contextMenu from './contextMenu.vue';
import menuBtnGroups from './menuBtnGroups.vue';
import fieldList from './fieldList.vue';
import attrConfig from './attrConfig.vue';
import { mapState } from 'vuex';

import shdFormDesignText from './components/input.vue';
import shdModelComp from './components/modelComp.vue';
export default {
  name: 'SHDFormDesigner',
  components: {
    boxArea,
    menuBtnGroups,
    contextMenu,
    fieldList,
    attrConfig,
    shdModelComp,
    'shdFormDesign-text': shdFormDesignText
  },
  data() {
    return {
      template: {
        loading: false,
        id: null
      },
      startXGuide: 0,
      changeXAxisIndex: -1,
      xSublineGuideLeft: 0,
      showXSubline: false,
      showXSublineGuide: false,
      startYGuide: 0,
      changeYAxisIndex: -1,
      ySublineGuideTop: 0,
      showYSubline: false,
      showYSublineGuide: false,
      tooltip: {
        color: '',
        bgcolor: '',
        fontSize: 12,
        'font-weight': ['bold', 'normal'],
        'font-style': ['italic', 'normal'],
        'text-decoration': ['underline', 'none']
      },
      rules: {
        rows: [{ required: true, message: '请输入行数', trigger: 'change' }],
        columns: [{ required: true, message: '请输入列数', trigger: 'change' }]
      },
      contextMenu: {
        top: 0,
        left: 0
      },
      startX: '',
      startY: '',
      moveX: '',
      moveY: '',
      oldMoveX: '',
      oldMoveY: '',
      heightArray: [],
      boxStyle: {
        width: 0,
        height: 0,
        top: 0,
        left: 0
      },
      showBoxArea: false,
      showContextMenu: false,
      propertyList: propertyList,
      editorAreaClass: 'editorArea'
    };
  },
  computed: {
    ...mapState({
      cellInfo: (state) => state.form.cellInfo,
      dataJson: (state) => state.form.dataJson,
      apiJson: (state) => state.form.apiJson,
      submitJson: (state) => state.form.submitJson,
      dictJson: (state) => state.form.dictJson,
      histroyData: (state) => state.form.histroyData,
      histroyIndex: (state) => state.form.histroyIndex,
      baseTableConfig: (state) => state.form.baseTableConfig,
      boxAreaXY: (state) => state.form.boxAreaXY,
      xAxisNum: (state) => state.form.xAxisNum,
      yAxisNum: (state) => state.form.yAxisNum
    }),
    canvasStyle() {
      // +1修复表格边框线重叠问题导致X轴换行
      let xLen =
        this.xAxisNum.reduce((pre, cur) => {
          return pre + cur.width;
        }, 50) + 1;
      let yLen = this.yAxisNum.reduce((pre, cur) => {
        return pre + cur.height;
      }, this.baseTableConfig.cellHeight);
      return {
        width: xLen + 'px',
        height: yLen + 'px'
      };
    },
    boxAreaStyle() {
      return {
        width: this.boxStyle.width + 'px',
        height: this.boxStyle.height + 'px',
        left: this.boxStyle.left + 'px',
        top: this.boxStyle.top + 'px'
      };
    },
    computedTableStyle() {
      if (this.dataJson.tableTotalWidth) {
        return {
          width: this.dataJson.tableTotalWidth + 'px'
          // width: '100%'
        };
      }
    },
    computedTdStyle(style) {
      return (style) => {
        return {
          ...style,
          'font-size': (style['font-size'] || 12) + 'px',
          height: (style.height || this.baseTableConfig.cellHeight) - 1 + 'px',
          'line-height': (style.height || this.baseTableConfig.cellHeight) - 1 + 'px'
        };
      };
    },
    computedComponentStyle(style) {
      return (style) => {
        return {
          width: (style.width || this.baseTableConfig.cellWidth) - 1 + 'px',
          'font-size': (style['font-size'] || 12) + 'px',
          height: (style.height || this.baseTableConfig.cellHeight) - 1 + 'px',
          'line-height': (style.height || this.baseTableConfig.cellHeight) - 1 + 'px'
        };
      };
    },
    formatterCompType(type) {
      return (type) => {
        return 'shdFormDesign-' + (type || 'text');
      };
    },
    isNotSameCell() {
      return isClickSameCell(this.boxAreaXY.startX, this.boxAreaXY.startY, this.boxAreaXY.endX, this.boxAreaXY.endY);
    },
    disableCellWidthAndHeight(cellInfo) {
      return (cellInfo) => {
        if (!cellInfo.xName || cellInfo.merge[0] != 1 || cellInfo.merge[1] != 1) {
          return true;
        } else {
          return false;
        }
      };
    },
    frontXAxisTotalWidth() {
      return this.xAxisNum
        .filter((item, index) => index < this.changeXAxisIndex)
        .reduce((pre, cur) => {
          return pre + cur.width;
        }, 0);
    },
    frontYAxisTotalHeight() {
      return this.yAxisNum
        .filter((item, index) => index < this.changeYAxisIndex)
        .reduce((pre, cur) => {
          return pre + cur.height;
        }, 0);
    },
    computedPrintLineStyle() {
      let pageStyle = pageSizeInPixels(this.dataJson.printConfig.format || 'a4');
      console.log('纸的像素尺寸：宽 ' + pageStyle.width + 'px, 高 ' + pageStyle.height + 'px');
      return {
        left: pageStyle.width + 50 + 'px'
      };
    }
  },
  beforeDestroy() {
    this.$store.commit('form/clearDesignerData');
    window.removeEventListener('keydown', this.keyboardEvent, false);
    this.$refs.tableDom.removeEventListener('paste', this.handleParsePasteData, false);
  },
  methods: {
    async initDesigner(id) {
      if (id) {
        // 编辑渲染表单
        this.template.loading = true;
        this.template.id = id;
        await this.$store.dispatch('form/getFormTemplate', { id });
        this.template.loading = false;
      } else {
        this.template.id = null;
        this.$store.commit('form/initFormTemplate');
      }
      this.$store.dispatch('form/getApiList');
      this.bindEvent();
    },
    bindEvent() {
      window.addEventListener('keydown', this.keyboardEvent, false);
      this.bindPasteEvent();
    },
    bindPasteEvent() {
      if (this.$refs.tableDom) {
        this.$refs.tableDom.addEventListener('paste', this.handleParsePasteData, false);
      }
    },
    handleClickEditor(e) {
      let target = e.target;
      console.log(target.className);
      if (target.className == 'editor-canvas') {
        // 点击空白处
        this.hideContextMenu();
        this.$store.commit('form/setCellInfo', {});
        this.clearBoxAreaStyle();
        this.$refs.attrConfig.showTemplateInfo = true;
        this.$refs.attrConfig.tabsActive = '1';
        this.xAxisNum.forEach((item) => {
          item.active = false;
          item.selected = false;
        });
        this.yAxisNum.forEach((item) => {
          item.active = false;
          item.selected = false;
        });
      } else if (target.className.includes('x-Axis-item') || target.className.includes('y-Axis-item')) {
        this.hideContextMenu();
        this.$store.commit('form/setCellInfo', {});
        this.$refs.attrConfig.showTemplateInfo = true;
        this.$refs.attrConfig.tabsActive = '1';
      } else if (target.className.includes('boxArea-border')) {
        this.hideContextMenu();
        this.$store.commit('form/setCellInfo', {});
        this.clearBoxAreaStyle();
        this.$refs.attrConfig.showTemplateInfo = true;
        this.$refs.attrConfig.tabsActive = '1';
        this.xAxisNum.forEach((item) => {
          item.active = false;
          item.selected = false;
        });
        this.yAxisNum.forEach((item) => {
          item.active = false;
          item.selected = false;
        });
      } else {
        this.$refs.attrConfig.showTemplateInfo = false;
        this.$refs.attrConfig.tabsActive = '1';
      }
    },
    handleFormatterCopyData(dom) {
      let copyData = [];
      const tableDom = dom.querySelector('table');
      if (!tableDom) return [];
      tableDom.querySelectorAll('tr').forEach((item, rowIndex) => {
        let tdDoms = item.querySelectorAll('td');
        copyData.push({
          cells: []
        });
        if (tdDoms) {
          tdDoms.forEach((tdItem) => {
            let tdText = tdItem.innerText.replace(/\n/g, '').trim();
            copyData[rowIndex].cells.push({
              value: tdText
            });
          });
        }
      });
      return copyData;
    },
    handleParsePasteData(e) {
      const that = this;
      // 获取粘贴板数据
      if (!that.cellInfo.isEdit) {
        that.$message.warning('请先双击单元格再进行粘贴操作！');
        return false;
      }
      let target = e.target;
      let parentTarget = findParentWithClass(target, 'template-table');
      if (!parentTarget) {
        return;
      }
      Array.from(e.clipboardData.items).forEach((item, index) => {
        const type = e.clipboardData.types[index];
        if (item.kind === 'string') {
          if (type === 'text/html') {
            that.handleHtmlPaste(item);
          }
        }
      });
      // 存进历史记录
      that.$store.commit('form/addHistroyData', {
        type: 'paste',
        data: structuredClone(that.dataJson)
      });
    },
    // 处理HTML粘贴（Excel复制粘贴）
    handleHtmlPaste(item) {
      const that = this;
      item.getAsString((htmlStr) => {
        const dom = new DOMParser().parseFromString(htmlStr, 'text/html');
        const copyData = that.handleFormatterCopyData(dom);
        // 多单元格数据粘贴
        let isMultiple = copyData.filter((item) => item.cells.length > 0).length > 1;
        if (isMultiple) {
          const { x, y } = that.cellInfo;
          copyData.forEach((row, rowIndex) => {
            const rowData = that.dataJson.rows[y - 1 + rowIndex];
            if (!rowData) return;
            row.cells.forEach((cell, cellIndex) => {
              if (x - 1 + cellIndex >= rowData.cells.length) return;
              const targetCell = rowData.cells[x - 1 + cellIndex];
              if (cell.value && targetCell) {
                targetCell.code = cell.value;
                targetCell.value = cell.value;
                if (rowIndex === 0 && cellIndex === 0) {
                  that.cellInfo.code = cell.value;
                  that.cellInfo.value = cell.value;
                }
              }
            });
          });
        }
      });
    },
    getCellAttributes(cell) {
      return {
        x: Number(cell.getAttribute('x')),
        y: Number(cell.getAttribute('y')),
        rowspan: Number(cell.getAttribute('rowspan') || 1),
        colspan: Number(cell.getAttribute('colspan') || 1)
      };
    },
    // 设置起始坐标
    setInitialCoordinates(x, y) {
      this.startX = x;
      this.startY = y;
      this.moveX = x;
      this.moveY = y;
    },
    // 基于起始坐标初始化框选区域
    initializeBoxArea(startX, startY) {
      this.showBoxArea = true;
      const top = this.calculateOffset(this.yAxisNum, startY, 'height', 30);
      const left = this.calculateOffset(this.xAxisNum, startX, 'width', 50);
      this.boxStyle = { top, left, width: 0, height: 0 };

      console.log(this.boxStyle, 'this.boxStyle');
    },
    // 根据轴配置计算偏移量的实用工具函数
    calculateOffset(axis, index, dimension, initialOffset) {
      return axis.filter((item, idx) => idx < index).reduce((acc, cur) => acc + cur[dimension], initialOffset);
    },
    handleMouseDown(e) {
      const that = this;

      if (!that.startX) e.preventDefault();

      let target = e.target;
      let parentTarget = findParentWithClass(target, 'tdCell');
      if (!parentTarget || !parentTarget.className.includes('tdCell')) {
        return false;
      }
      const { x, y, rowspan, colspan } = that.getCellAttributes(e.target);
      // 设置鼠标按下时的初始坐标
      that.setInitialCoordinates(x, y);

      // button => 0 左击 1 滚轮 2 右击
      if (e.button == 2) {
        that.handleCellClick({ y: that.startY, x: that.startX, merge: [rowspan, colspan] });
        return;
      }

      that.hideContextMenu();

      if (that.showBoxArea) return;

      // 基于起始坐标初始化框选区域
      that.initializeBoxArea(x, y);

      const handleMouseMove = (moveEvent) => {
        let target = moveEvent.target;
        let parentTarget = findParentWithClass(target, 'tdCell');

        // 如果没有框选区域或鼠标不在单元格内，直接返回
        if (!that.showBoxArea || !parentTarget || !parentTarget.className.includes('tdCell')) {
          return false;
        }

        // 提取目标单元格的属性
        const { x, y, rowspan, colspan } = that.getCellAttributes(target);
        that.moveX = x;
        that.moveY = y;
        // 如果鼠标位置没有变化，则不继续处理
        if (x === that.oldMoveX && y === that.oldMoveY) {
          return;
        }
        // 更新记录的坐标
        that.oldMoveX = x;
        that.oldMoveY = y;

        // 根据鼠标移动的方向可能需要调整起始坐标
        let newStartX = Math.min(that.startX, x);
        let newEndX = Math.max(that.startX, x + colspan - 1);
        let newStartY = Math.min(that.startY, y);
        let newEndY = Math.max(that.startY, y + rowspan - 1);

        // 更新框选区域的尺寸
        that.updateBoxAreaDimensions(newStartX, newStartY, newEndX, newEndY);
      };

      const handleMouseUp = (e) => {
        document.removeEventListener('mousemove', handleMouseMove);
        document.removeEventListener('mouseup', handleMouseUp);
        that.heightArray = [];
        // 开始结束不在一个单元格内 绘制框选区域 同时激活坐标轴active属性
        let isSameCell = isClickSameCell(that.startX, that.startY, that.moveX, that.moveY);
        if (isSameCell) {
          that.$store.commit('form/setBoxAreaXY', {
            x1: that.startX,
            y1: that.startY,
            x2: that.moveX,
            y2: that.moveY
          });
          // 激活坐标轴active属性
          let endCell = that.dataJson.rows[that.moveY].cells[that.moveX];
          let endX = that.moveX;
          let endY = that.moveY;
          if (endCell && endCell.merge[0] > 1) {
            endY = that.moveY + endCell.merge[0] - 1;
          }
          if (endCell && endCell.merge[1] > 1) {
            endX = that.moveX + endCell.merge[1] - 1;
          }

          let newStartX = Math.min(that.startX, endX);
          let newEndX = Math.max(that.startX, endX);
          let newStartY = Math.min(that.startY, endY);
          let newEndY = Math.max(that.startY, endY);
          that.handleAxisActiveProperty(that.createArray(newStartY, newEndY), that.createArray(newStartX, newEndX));
          // that.handleAxisActiveProperty(that.createArray(that.startY, that.startY + height - 1), that.createArray(that.startX, that.moveX));
        }
        that.oldMoveX = that.oldMoveY = that.startX = that.startY = that.moveX = that.moveY = '';
      };

      document.addEventListener('mousemove', handleMouseMove, false);
      document.addEventListener('mouseup', handleMouseUp, false);
    },
    handleMouseUp(e) {
      if (this.showBoxArea) {
        // 0 左击 1 滚轮 2 右击
        if (e.button == 2) {
          let target = e.target;
          if (target.className == 'boxArea-border') {
            let top = e.layerY;
            let left = e.layerX;
            let { width, height } = this.getDistanceByIndex(this.boxAreaXY.startX, this.boxAreaXY.startY);
            this.contextMenu.top = top + height + 30;
            this.contextMenu.left = left + width + 50;
            this.showContextMenu = true;
          } else if (target.className.indexOf('x-Axis-item') > -1 || target.className.indexOf('y-Axis-item') > -1) {
            this.hideContextMenu();
            this.showBoxArea = false;
          }
        }
      }
    },
    updateBoxAreaDimensions(startX, startY, endX, endY) {
      const that = this;

      let width = 0;
      let height = 0;
      let top = 30;
      let left = 50;

      // 计算宽度
      for (let i = startX; i <= endX; i++) {
        width += that.xAxisNum[i].width;
      }

      // 计算高度
      for (let j = startY; j <= endY; j++) {
        height += that.yAxisNum[j].height;
      }
      // 计算top
      for (let t = 0; t < startY; t++) {
        top += that.yAxisNum[t].height;
      }

      // 计算left
      for (let l = 0; l < startX; l++) {
        left += that.xAxisNum[l].width;
      }

      // 设置新的框选区域位置和尺寸
      that.$set(that.boxStyle, 'top', top);
      that.$set(that.boxStyle, 'left', left);
      that.$set(that.boxStyle, 'width', width);
      that.$set(that.boxStyle, 'height', height);

      console.log(`Box dimensions updated: top = ${top}, left = ${left}, width = ${width}, height = ${height}`);
    },
    createArray(start, end) {
      const array = [];
      for (let i = start; i <= end; i++) {
        array.push(i);
      }
      return array;
    },
    clearBoxAreaStyle() {
      this.showBoxArea = false;
      Object.assign(this.boxStyle, {
        top: 0,
        left: 0,
        width: 0,
        height: 0
      });
      this.$store.commit('form/clearBoxAreaXY');
    },
    // y:y轴索引  x：x轴索引 merge:[rowspan,colspan]
    handleCellClick(cItem) {
      let { y, x, merge } = cItem;
      if (this.showBoxArea) {
        this.clearBoxAreaStyle();
      }
      this.xAxisNum.forEach((item) => {
        item.selected = false;
      });
      this.yAxisNum.forEach((item) => {
        item.selected = false;
      });
      this.setTdCellInfo(x, y);
      console.log(cItem, 'cItem点击事件');
    },
    handleCellDbClick(item) {
      if (item.type == 'text') {
        this.$set(item, 'isEdit', true);
        this.$nextTick(() => {
          this.$set(this.cellInfo, 'isEdit', true);
          let comp = this.$refs[item.x + '-' + item.y + '-comp'];
          if (comp && comp[0]) {
            comp[0].handleFocus(item.x, item.y);
          }
        });
      }
    },
    // 激活坐标轴active属性
    handleAxisActiveProperty(yIndexs, xIndexs) {
      for (let i = 0; i < this.yAxisNum.length; i++) {
        this.$set(this.yAxisNum[i], 'active', false);
        if (yIndexs.includes(i)) {
          this.$set(this.yAxisNum[i], 'active', true);
        }
      }
      for (let i = 0; i < this.xAxisNum.length; i++) {
        this.$set(this.xAxisNum[i], 'active', false);
        if (xIndexs.includes(i)) {
          this.$set(this.xAxisNum[i], 'active', true);
        }
      }
    },
    // 激活当前单元格信息
    setTdCellInfo(x, y) {
      let cellData = this.dataJson.rows[y].cells[x];
      let cellInfoStyle = cellData.style || {};
      // 清除所有可编辑数据
      this.dataJson.rows.forEach((row) => {
        row.cells.forEach((cell) => {
          this.$set(cell, 'isEdit', false);
          this.$set(cell, 'eventConfig', cell.eventConfig || {});
        });
      });
      // 初始化工具提示
      this.$refs.menuBtnGroups.initToolTip();

      // 更新提示工具信息和样式
      const tooltipMapping = {
        'font-size': 'fontSize',
        color: 'color',
        'background-color': 'bgcolor'
      };
      Object.entries(cellInfoStyle).forEach(([key, value]) => {
        if (tooltipMapping[key]) {
          this.$refs.menuBtnGroups.tooltip[tooltipMapping[key]] = value;
        }
      });
      // 设置选中单元格的详细信息
      this.$store.commit('form/setCellInfo', {
        ...cellData,
        x: x + 1,
        y: y + 1,
        xName: this.xAxisNum[x].label,
        style: cellInfoStyle,
        isEdit: cellData.isEdit || false,
        apiField: cellData.apiField || false,
        isForamtter: cellData.isForamtter || false,
        dataType: cellData.dataType || '1',
        eventConfig: cellData.eventConfig || {}
      });
      // 激活相关的坐标轴属性
      let endX = x + ((cellData.merge && cellData.merge[1]) || 1) - 1;
      let endY = y + ((cellData.merge && cellData.merge[0]) || 1) - 1;
      this.handleAxisActiveProperty(this.createArray(y, endY), this.createArray(x, endX));
    },
    // 框选合并/拆分
    command(type) {
      const that = this;
      switch (type) {
        case 'handleMerge':
          break;
        case 'handleSplit':
          break;
        case 'handleDeleteRows':
          break;
        case 'handleDeleteColumns':
          break;
        case 'handleClearCellInfo':
          this.$refs.menuBtnGroups.initToolTip();
          break;
        case 'handleAddRows':
          break;
        case 'handleRequired':
          break;
        case 'handleCancelRequired':
          break;
        default:
          break;
      }
      that.clearBoxAreaStyle();
      that.hideContextMenu();
    },
    // 隐藏菜单
    hideContextMenu() {
      this.showContextMenu = false;
      this.contextMenu.top = 0;
      this.contextMenu.left = 0;
    },
    // 根据坐标获取距离
    getDistanceByIndex(x, y) {
      let width = this.xAxisNum
        .filter((item) => item.index <= x)
        .reduce((pre, cur) => {
          return pre + cur.width;
        }, 0);
      let height = this.yAxisNum
        .filter((item) => item.index <= y)
        .reduce((pre, cur) => {
          return pre + cur.height;
        }, 0);
      return {
        width,
        height
      };
    },
    handleContextMenu(e) {
      e.stopPropagation();
      e.preventDefault();
      // 计算菜单相对于编辑器的位移
      let target = e.target;
      console.log(target, 'target');
      let top = e.layerY;
      let left = e.layerX;
      let parentTarget = findParentWithClass(target, 'tdCell');

      if (!parentTarget || !parentTarget.className.includes('tdCell')) {
        return false;
      }

      let x = Number(parentTarget.getAttribute('x'));
      let y = Number(parentTarget.getAttribute('y'));

      this.setTdCellInfo(x, y);

      let xDistance = this.xAxisNum.filter((item, index) => index < x).reduce((pre, cur) => pre + cur.width, 0);
      let yDistance = this.yAxisNum.filter((item, index) => index < y).reduce((pre, cur) => pre + cur.height, 0);

      this.showContextMenu = true;
      this.contextMenu.top = top + 30 + yDistance;
      this.contextMenu.left = left + 50 + xDistance;
    },
    // X轴批量激活
    batchXActive(item) {
      const that = this;
      let columnIndex = item.index - 1;
      that.xAxisNum.forEach((item) => {
        item.active = false;
        item.selected = false;
      });

      if (!item.active) {
        item.selected = true;
        that.showBoxArea = true;
        that.yAxisNum.forEach((item) => {
          item.active = true;
          item.selected = false;
        });
        let left = that.xAxisNum.filter((item, index) => index < columnIndex).reduce((pre, cur) => pre + cur.width, 0);
        let width = that.xAxisNum.find((item, index) => index == columnIndex).width;
        let height = that.yAxisNum.reduce((pre, cur) => pre + cur.height, 0);
        that.$set(that.boxStyle, 'top', 30);
        that.$set(that.boxStyle, 'left', left + 50);
        that.$set(that.boxStyle, 'width', width);
        that.$set(that.boxStyle, 'height', height);

        that.$store.commit('form/setBoxAreaXY', {
          x1: columnIndex,
          y1: 0,
          x2: columnIndex,
          y2: that.dataJson.rows.length - 1
        });
      }
    },
    // Y轴批量激活
    batchYActive(item) {
      const that = this;
      let rowIndex = item.index - 1;
      that.yAxisNum.forEach((item) => {
        item.active = false;
        item.selected = false;
      });

      if (!item.active) {
        item.selected = true;
        that.showBoxArea = true;
        that.xAxisNum.forEach((item) => {
          item.active = true;
          item.selected = false;
        });
        let top = that.yAxisNum.filter((item, index) => index < rowIndex).reduce((pre, cur) => pre + cur.height, 0);
        let width = that.xAxisNum.reduce((pre, cur) => pre + cur.width, 0);
        let height = that.yAxisNum.find((item, index) => index == rowIndex).height;
        that.$set(that.boxStyle, 'top', top + 30);
        that.$set(that.boxStyle, 'left', 50);
        that.$set(that.boxStyle, 'width', width);
        that.$set(that.boxStyle, 'height', height);

        that.$store.commit('form/setBoxAreaXY', {
          x1: 0,
          y1: rowIndex,
          x2: that.dataJson.rows[0].cells.length - 1,
          y2: rowIndex
        });
      }
    },
    computedNotHide(cell) {
      return cell.filter((item) => !item.hide);
    },
    handleXAxisMouseMove(e) {
      const that = this;
      let target = e.target;

      if (target.classList.contains('x-Axis-item')) {
        if (that.showXSubline) {
          that.xSublineGuideLeft = e.layerX;
        }
        let xIndex = Number(target.getAttribute('index'));
        let { width } = that.getDistanceByIndex(xIndex + 1, 0);
        if (width - (e.layerX - 50) < 15) {
          that.showXSublineGuide = true;
          let left = width + 50 - 5;
          that.xSublineGuideLeft = left;
          if (!that.showXSubline) {
            that.changeXAxisIndex = xIndex;
          }
        } else {
          if (!that.showXSubline) {
            that.showXSublineGuide = false;
          }
        }
      } else {
        that.showXSublineGuide = true;
      }
    },
    handleXAxisMouseUp(e) {
      const that = this;
      let target = e.target;
      that.showXSublineGuide = false;
      that.showXSubline = false;
      if (!target.classList.contains('x-Axis-item')) {
        if (that.changeXAxisIndex == 0) {
          that.xAxisNum[that.changeXAxisIndex].width = that.xSublineGuideLeft - 50;
          that.dataJson.rows.map((rItem) => {
            rItem.cells.map((cItem, cIndex) => {
              if (cIndex === this.changeXAxisIndex) {
                cItem.style.width = that.xSublineGuideLeft - 50;
              }
            });
          });
        } else {
          let direction = that.startXGuide - e.clientX > 0 ? 'left' : 'right';
          // 获取x轴点击索引前的宽度总和
          let frontXAxisTotalWidth = 0;
          frontXAxisTotalWidth = that.xAxisNum
            .filter((item, index) => {
              return index < that.changeXAxisIndex;
            })
            .reduce((pre, cur) => {
              return pre + cur.width;
            }, 0);
          let translateX = that.xSublineGuideLeft - frontXAxisTotalWidth - 50;
          if (direction == 'left') {
            // TODO:最小宽度30
            if (translateX < 30) {
              translateX = 30;
            }
          }
          that.dataJson.rows.map((rItem) => {
            rItem.cells.map((cItem, cIndex) => {
              if (cIndex === this.changeXAxisIndex) {
                if (cItem.merge[1] > 1) {
                  cItem.style.width = cItem.style.width + translateX - that.xAxisNum[that.changeXAxisIndex].width;
                } else {
                  cItem.style.width = translateX;
                }
              }
            });
          });
          console.log(that.xAxisNum[that.changeXAxisIndex], 'that.xAxisNum[that.changeXAxisIndex]');
          that.xAxisNum[that.changeXAxisIndex].width = translateX;
        }

        this.$store.commit('form/initAxis', {
          cellWidth: this.baseTableConfig.cellWidth,
          cellHeight: this.baseTableConfig.cellHeight
          // rowIndex: this.cellInfo.x - 1
        });

        console.log(that.xAxisNum, 'that.xAxisNum');

        that.dataJson.rows.map((rItem) => {
          rItem.cells.map((cItem, cIndex) => {
            if (cIndex === this.changeXAxisIndex) {
              if (cItem.mergeCell) {
                let mergeCell = cItem.mergeCell;
                let x = mergeCell.split('-')[0];
                let y = mergeCell.split('-')[1];
                let targetCell = that.dataJson.rows[y].cells[x];
                let targetCellStart = targetCell.x;
                let targetCellEnd = Number(targetCell.x) + targetCell.merge[1];
                let targetCellWidth = that.xAxisNum
                  .filter((item, index) => {
                    return index >= targetCellStart && index < targetCellEnd;
                  })
                  .reduce((pre, cur) => {
                    return pre + cur.width;
                  }, 0);
                targetCell.style.width = targetCellWidth;
              }
            }
          });
        });

        // this.$store.commit('form/setTableTotalWidth');

        if (this.showBoxArea) {
          // 更新boxArea的样式
          let { left, top, width, height } = calculateBoxAreaStyle(that.xAxisNum, that.yAxisNum, that.boxAreaXY);
          that.$set(that.boxStyle, 'top', top);
          that.$set(that.boxStyle, 'left', left);
          that.$set(that.boxStyle, 'width', width);
          that.$set(that.boxStyle, 'height', height);
          console.log(that.boxAreaXY, 'that.boxAreaXY');
          console.log(that.boxAreaStyle, 'that.boxAreaStyle');
        }
      }
      // this.changeXAxisIndex = -1;
    },
    handleXGuideMouseDown(e) {
      this.showXSubline = true;
      this.startXGuide = e.clientX;
    },
    handleXGuideMouseUp(e) {
      this.showXSubline = false;
    },
    handleYAxisMouseMove(e) {
      const that = this;
      let target = e.target;
      console.log(target, 'target');
      if (target.classList.contains('y-Axis-item')) {
        if (that.showYSubline) {
          that.ySublineGuideTop = e.layerY;
        }
        let yIndex = Number(target.getAttribute('index'));
        let { height } = that.getDistanceByIndex(0, yIndex + 1);
        if (height - (e.layerY - 30) < 10) {
          that.showYSublineGuide = true;
          let top = height + 30 - 5;
          that.ySublineGuideTop = top;
          if (!that.showYSubline) {
            that.changeYAxisIndex = yIndex;
          }
        } else {
          if (!that.showYSubline) {
            that.showYSublineGuide = false;
          }
        }
      } else {
        that.showYSublineGuide = true;
      }
    },
    handleYAxisMouseUp(e) {
      const that = this;
      let target = e.target;
      that.showYSublineGuide = false;
      that.showYSubline = false;
      if (!target.classList.contains('y-Axis-item')) {
        if (that.changeYAxisIndex == 0) {
          that.yAxisNum[that.changeYAxisIndex].height = that.ySublineGuideTop - 30;
          that.dataJson.rows.map((rItem, rIndex) => {
            if (rIndex == this.changeYAxisIndex) {
              console.log(rItem);
              rItem.height = that.ySublineGuideTop - 30;
              rItem.cells.map((cItem, cIndex) => {
                cItem.style.height = that.ySublineGuideTop - 30;
              });
            }
          });
        } else {
          let direction = that.startYGuide - e.clientY > 0 ? 'top' : 'bottom';
          // 获取y轴点击索引前的高度总和
          let frontYAxisTotalHeight = 0;
          frontYAxisTotalHeight = that.yAxisNum
            .filter((item, index) => {
              return index < that.changeYAxisIndex;
            })
            .reduce((pre, cur) => {
              return pre + cur.height;
            }, 0);
          let translateY = that.ySublineGuideTop - frontYAxisTotalHeight - 30;
          if (direction == 'top') {
            // TODO:最小高度20
            if (translateY < 20) {
              translateY = 20;
            }
          }
          console.log(translateY, 'translateY');
          that.dataJson.rows.map((rItem, rIndex) => {
            // rItem.cells.map((cItem, cIndex) => {
            //   if (cIndex === this.changeYAxisIndex) {
            //     if (cItem.merge[0] > 1) {
            //       cItem.style.width = cItem.style.width + translateY - that.yAxisNum[that.changeYAxisIndex].width;
            //     } else {
            //       cItem.style.width = translateY;
            //     }
            //   }
            // });
            if (rIndex === this.changeYAxisIndex) {
              // rItem.height = translateY;
              rItem.cells.map((cItem, cIndex) => {
                if (cItem.merge[0] > 1) {
                  cItem.style.height = cItem.style.height + translateY - that.yAxisNum[that.changeYAxisIndex].height;
                } else {
                  cItem.style.height = translateY;
                }
              });
            }
          });
          console.log(that.dataJson.rows, 'that.dataJson.rows');
          that.yAxisNum[that.changeYAxisIndex].height = translateY;
          console.log(that.yAxisNum[that.changeYAxisIndex].height, 'that.yAxisNum[that.changeYAxisIndex]');
        }

        // this.$store.commit('form/initAxis', {
        //   cellWidth: this.baseTableConfig.cellWidth,
        //   cellHeight: this.baseTableConfig.cellHeight
        // });

        console.log(that.yAxisNum[that.changeYAxisIndex], 'that.yAxisNum[that.changeYAxisIndex]');

        that.dataJson.rows.map((rItem, rIndex) => {
          if (rIndex == this.changeYAxisIndex) {
            rItem.cells.map((cItem, cIndex) => {
              if (cItem.mergeCell) {
                let mergeCell = cItem.mergeCell;
                let x = mergeCell.split('-')[0];
                let y = mergeCell.split('-')[1];
                let targetCell = that.dataJson.rows[y].cells[x];
                let targetCellStart = targetCell.y;
                let targetCellEnd = Number(targetCell.y) + targetCell.merge[0];
                let targetCellHeight = that.yAxisNum
                  .filter((item, index) => {
                    return index >= targetCellStart && index < targetCellEnd;
                  })
                  .reduce((pre, cur) => {
                    return pre + cur.height;
                  }, 0);
                targetCell.style.height = targetCellHeight;
              }
            });
          }
        });

        if (this.showBoxArea) {
          // 更新boxArea的样式
          let { left, top, width, height } = calculateBoxAreaStyle(that.xAxisNum, that.yAxisNum, that.boxAreaXY);
          that.$set(that.boxStyle, 'top', top);
          that.$set(that.boxStyle, 'left', left);
          that.$set(that.boxStyle, 'width', width);
          that.$set(that.boxStyle, 'height', height);
          console.log(that.boxAreaXY, 'that.boxAreaXY');
          console.log(that.boxAreaStyle, 'that.boxAreaStyle');
        }
      }
      // this.changeXAxisIndex = -1;
    },
    handleYGuideMouseDown(e) {
      this.showYSubline = true;
      this.startYGuide = e.clientX;
    },
    handleYGuideMouseUp(e) {
      this.showYSubline = false;
    },
    // ctrl快捷键操作
    keyboardEvent(e) {
      const that = this;
      const keyCodes = {
        90: 'z',
        89: 'y',
        67: 'c',
        83: 's',
        86: 'v',
        68: 'd',
        37: 'left',
        38: 'top',
        39: 'right',
        40: 'bottom'
      };
      const { ctrlKey, keyCode } = e;
      let keyString = [];
      if (ctrlKey) keyString.push('ctrl');
      keyString.push(keyCodes[keyCode]);
      keyString = keyString.join('+');
      switch (keyString) {
        case 'ctrl+z':
          that.$store.commit('form/undo');
          break;
        case 'ctrl+y':
          that.$store.commit('form/redo');
          break;
        case 'ctrl+s':
          e.preventDefault();
          that.handleSave();
          break;
        case 'left':
          that.handleMouseLeft();
          break;
        case 'top':
          that.handleMouseTop();
          break;
        case 'right':
          that.handleMouseRight();
          break;
        case 'bottom':
          that.handleMouseBottom();
          break;
        default:
          break;
      }
    },
    handleSave() {
      const that = this;
      if (that.dataJson.rows.length == 0) {
        this.$message.warning('请先初始化表格');
        return;
      }
      console.log(that.dataJson, 'that.dataJson');
      if (!that.template.id) {
        // 新增保存
        that.$refs.menuBtnGroups.template.visible = true;
      } else {
        // 编辑保存
        that.dataJson.id = that.template.id;
        that.$store.dispatch('form/saveForm', {
          apiJson: that.apiJson,
          dataJson: that.dataJson,
          submitJson: that.submitJson,
          dictJson: that.dictJson
        });
      }
    },
    // 新增模板成功
    handleAddTemplateSuccess() {
      this.$emit('addTemplateSuccess');
    },
    handleCompInput(config) {
      let { value, x, y } = config;
      this.cellInfo.value = value;
      this.cellInfo.code = value;
      // this.dataJson.rows[y].cells[x].isEdit = false;
      this.dataJson.rows[y].cells[x].value = value;
      this.dataJson.rows[y].cells[x].code = value;
    },
    handleCompChange(config) {
      let { value, x, y } = config;
      this.$set(this.cellInfo, 'value', '');
      this.$set(this.dataJson.rows[y].cells[x], 'value', '');
    },
    handleDrop(e, item) {
      e.preventDefault();
      let isApi = e.dataTransfer.getData('apifield');
      let data = null;
      if (isApi) {
        // 接收api字段
        let apiData = JSON.parse(e.dataTransfer.getData('apifield'));
        data = `#{${apiData.key}.${apiData.value}}`;
        this.$set(this.dataJson.rows[item.y].cells[item.x], 'apiField', true);
      }
      this.cellInfo.code = data;
      this.dataJson.rows[item.y].cells[item.x].code = data;
    },
    initForm(initTable) {
      this.template.loading = true;
      this.$store.commit('form/initForm', {
        rows: initTable.rows,
        columns: initTable.columns,
        cellWidth: initTable.cellWidth,
        cellHeight: initTable.cellHeight
      });
      setTimeout(() => {
        this.bindPasteEvent();
        this.template.loading = false;
      }, 100);
    },
    handleToggleAttr() {
      if (this.editorAreaClass == 'editorArea') {
        this.editorAreaClass = 'editorArea attrConfig';
      } else {
        this.editorAreaClass = 'editorArea';
      }
      this.$refs.attrConfig.toggleWidth();
    },
    handleMouseLeft() {
      const that = this;
      let { x, y } = that.cellInfo;
      if (x <= 1) return;
      const leftCell = that.dataJson.rows[y - 1].cells[x - 1 - 1];
      console.log(leftCell, 'leftCell');
      if (!leftCell.hide) {
        that.handleCellClick(leftCell);
      } else {
        let mergeCell = leftCell.mergeCell;
        if (mergeCell) {
          let x = mergeCell.split('-')[0];
          let y = mergeCell.split('-')[1];
          that.handleCellClick(that.dataJson.rows[y].cells[x]);
        }
      }
    },
    handleMouseTop() {
      const that = this;
      let { x, y } = that.cellInfo;
      if (y <= 1) return;
      const topCell = that.dataJson.rows[y - 1 - 1].cells[x - 1];
      console.log(topCell, 'topCell');
      if (!topCell.hide) {
        that.handleCellClick(topCell);
      } else {
        let mergeCell = topCell.mergeCell;
        if (mergeCell) {
          let x = mergeCell.split('-')[0];
          let y = mergeCell.split('-')[1];
          that.handleCellClick(that.dataJson.rows[y].cells[x]);
        }
      }
    },
    handleMouseRight() {
      const that = this;
      let { x, y, merge } = that.cellInfo;
      if (x >= that.dataJson.rows[y - 1].cells.length) return;
      const rightCell = that.dataJson.rows[y - 1].cells[x - 1 + merge[1]];
      console.log(rightCell, 'rightCell');
      if (!rightCell.hide) {
        that.handleCellClick(rightCell);
      } else {
        if (rightCell.mergeCell) {
          let mergeCell = rightCell.mergeCell;
          if (mergeCell) {
            let x = mergeCell.split('-')[0];
            let y = mergeCell.split('-')[1];
            that.handleCellClick(that.dataJson.rows[y].cells[x]);
          }
        }
      }
    },
    handleMouseBottom() {
      const that = this;
      let { x, y, merge } = that.cellInfo;
      if (y >= that.dataJson.rows.length) return;
      const bottomCell = that.dataJson.rows[y - 1 + merge[0]].cells[x - 1];
      console.log(bottomCell, 'bottomCell');
      if (!bottomCell.hide) {
        that.handleCellClick(bottomCell);
      } else {
        if (bottomCell.mergeCell) {
          let mergeCell = bottomCell.mergeCell;
          if (mergeCell) {
            let x = mergeCell.split('-')[0];
            let y = mergeCell.split('-')[1];
            that.handleCellClick(that.dataJson.rows[y].cells[x]);
          }
        }
      }
    }
  }
};
</script>
<style scoped lang="scss">
$primary-color: #009688;
$bg-dark: #1d1e1f;
$border-color: #282e3a;
$axis-bg: #f4f5f8;
$selected-bg: #8eb0e7;
$active-bg: #dcdcdc;
$grid-border: #e6e6e6;

.designer {
  .container {
    position: relative;
    height: calc(100vh - 55px);
    background-color: #fff;

    .editorArea {
      position: absolute;
      left: 350px;
      width: calc(100% - 700px);
      height: 100%;
      box-sizing: border-box;
      transition: width 0.2s linear;

      &.attrConfig {
        width: calc(100% - 350px);
        transition: 0.2s width linear;
      }

      .editor-baseInfo {
        height: 39px;
        line-height: 39px;
        font-size: 14px;
        font-weight: bold;
        padding-left: 5px;
        color: $primary-color;
        border-bottom: 1px solid $border-color;
        background-color: $bg-dark;
        user-select: none;
        display: flex;
        justify-content: flex-start;
        align-items: center;
        &-name {
          white-space: nowrap;
          margin-right: 10px;
        }
        .legend {
          display: flex;
          justify-content: flex-start;
          align-items: center;
          font-size: 12px;
          height: 30px;

          .legend-item {
            height: 30px;
            line-height: 30px;
            padding: 0 5px;
            margin-right: 10px;
            border-radius: 5px;

            &.api {
              background-color: #ff4b4b; // 红色背景表示API接口数据
              color: #fff;
            }
          }
        }
        .btnGroups {
          margin-right: 5px;
          cursor: pointer;
        }
      }

      .editor-canvas {
        position: absolute;
        left: 0;
        top: 80px;
        width: 100%;
        height: calc(100% - 80px);
        overflow: scroll;

        .grid-canvas {
          position: relative;
          width: 100%;
          height: 100%;

          .x-Axis,
          .y-Axis {
            position: absolute;
            top: 0;
            left: 0;
            background-color: $axis-bg;
          }

          .x-Axis {
            width: 100%;
            height: 30px;
            border-top: 1px solid $grid-border;

            .x-Axis-item {
              display: inline-block;
              width: 100px;
              height: 100%;
              line-height: 30px;
              text-align: center;
              vertical-align: top;
              color: #000;
              border-right: 1px solid $grid-border;
              background-color: $axis-bg;
              user-select: none;

              &.origin {
                width: 50px;
              }
              &.active {
                background: $active-bg;
              }
              &.selected {
                background: $selected-bg;
              }
            }
            .x-subline-guide {
              position: absolute;
              top: 0;
              width: 5px;
              height: 100%;
              background-color: rgba(75, 137, 255, 0.25);
              z-index: 9;
              cursor: col-resize;
            }
            .x-subline {
              position: absolute;
              top: 0;
              left: 200px;
              width: 0;
              height: calc(100vh - 150px);
              border-right: 2px dashed #4b89ff;
              z-index: 6;
            }
            .x-width-tip {
              position: absolute;
              top: 0;
              background-color: #fff;
              border: 1px solid rgba(0, 0, 0, 0.08);
              border-radius: 1px;
              box-shadow: 0 2px 10px 0 rgb(0 0 0);
              color: rgba(0, 0, 0, 0.88);
              font-size: 12px;
              padding: 3px 10px 4px;
              white-space: nowrap;
            }
          }

          .y-Axis {
            width: 50px;
            height: 100%;

            .y-Axis-item {
              width: 100%;
              text-align: center;
              color: #000;
              border-bottom: 1px solid $grid-border;
              background-color: $axis-bg;
              user-select: none;

              &.origin {
                height: 30px;
              }
              &.active {
                background: $active-bg;
              }
              &.selected {
                background: $selected-bg;
              }
            }
            .y-subline-guide {
              position: absolute;
              left: 0;
              width: 100%;
              height: 5px;
              background-color: rgba(75, 137, 255, 0.25);
              z-index: 9;
              cursor: row-resize;
            }
            .y-subline {
              position: absolute;
              left: 0;
              top: 200px;
              height: 0;
              width: calc(100vw - 370px);
              border-bottom: 2px dashed #4b89ff;
              z-index: 6;
            }
            .y-width-tip {
              position: absolute;
              left: 0;
              background-color: #fff;
              border: 1px solid rgba(0, 0, 0, 0.08);
              border-radius: 1px;
              box-shadow: 0 2px 10px 0 rgb(0 0 0);
              color: rgba(0, 0, 0, 0.88);
              font-size: 12px;
              padding: 3px 10px 4px;
              white-space: nowrap;
              z-index: 99;
            }
          }

          table {
            position: absolute;
            left: 50px;
            top: 30px;
            table-layout: fixed;
            border-collapse: collapse;
            word-break: break-all;
            word-wrap: break-word;
            border-width: 0;
            tr {
              td {
                white-space: nowrap;
                overflow: hidden;
                background-color: #fff;
                user-select: none;
                text-align: center;
                position: relative;

                .lockIcon {
                  position: absolute;
                  top: 2px;
                  right: 2px;
                  font-size: 9px;
                }
                ::v-deep .el-input__inner {
                  background: #fff;
                }
                &.active {
                  background: linear-gradient(180deg, rgba(181, 209, 255, 0.34), rgba(181, 209, 255, 0.34));
                  ::v-deep .el-input__inner {
                    background: #ffeb3b;
                  }
                }
              }
            }
          }
          .print-line {
            min-height: calc(100vh - 150px);
            border-right: 2px dashed #009688;
            height: 100%;
            position: absolute;
            top: 0;
            z-index: 10;
          }
        }
      }
    }
  }
}
</style>
